﻿using System;
using System.Net;
using System.Collections.Generic;
using SCG.SolarVengeanceEngine.Orders;
using SCG.General;

namespace SCG.SolarVengeanceEngine.StarShips
{
    //InkSpots
    public class InkSpot : StarShip
    {
        //constructor
        public InkSpot(SVGame game, Player owner, int engines, StarSystem origin)
            : base(game, owner, engines, 0, origin)
        {
        }

        //ship name
        public override string Name
        {
            get
            {
                return "InkSpot";
            }
        }

        //description
        public override string Description
        {
            get
            {
                return "Any StarShip next to an InkSpot is \"tagged\".  The owner of the InkSpot can now see the full details of the \"tagged\" StarShip, even when its outside of Scanner range.  InkSpots also will automatically move away from adjacent enemy StarShips thanks to their evasive maneuvering systems.";
            }
        }

        //ship type
        public override StarShipType ShipType
        {
            get
            {
                return StarShipType.InkSpot;
            }
        }

        //Can target a starship
        public override bool CanExecuteOrder(OrderType ot)
        {
            switch (ot)
            {
                case OrderType.TargetStarShip:
                    return true;
                default:
                    return base.CanExecuteOrder(ot);
            }
        }

        //can it target a specific StarShip?
        public override bool CanTargetStarShip(StarShip ship, bool respectAlliance)
        {
            return !ship.OwnedByCurrentPlayer;
        }

        //private members

        //clear order if target is already tagged
        protected internal override void CommonPreProcessing()
        {
            if (Order != null)
                if (Order.OrderType == OrderType.TargetStarShip)
                {
                    MapObjectOrder moo = Order as MapObjectOrder;
                    StarShip target = moo.StarShip;
                    if (target.TaggedBy[Owner] || target.Owner == Owner)
                        Order = null;
                }
        }

        //tag adjacent ships
        protected internal override void CommonPostProcessing()
        {
            List<SCGPoint> adj = Game.AdjacentPoints(Location, false);
            foreach (SCGPoint pt in adj)
            {
                SVMapObject svm = Game.GetObjectAt((int)pt.X, (int)pt.Y);
                if (svm is StarShip)
                {
                    StarShip tagged = svm as StarShip;
                    tagged.DiscoveredBy[Owner] = true;
                    tagged.TaggedBy[Owner] = true;
                }
                else if (svm is UDO)
                {
                    //Inkspots also tag UDOs
                    UDO udo = svm as UDO;
                    if (udo.IsTaggable)
                        udo.TaggedBy[Owner] = true;
                }
            }           
        }

        //InkSpots will not move adjacent to an enemy starship
        protected internal override bool CanMoveTo(int x, int y)
        {          
            StarShip enemy = Game.AdjacentEnemyStarShip(this, x, y, false, true);
            if (enemy == null)
                return true;
            if (Order != null && Order is MapObjectOrder)
            {
                MapObjectOrder moo = Order as MapObjectOrder;
                return moo.MapObject == enemy;            
            }
            else
                return false;
        }

        //Perform evasive maneuvers during movement
        protected internal override bool MoveProcessing()
        {
            if (ProhibitMove)
                return false;
            StarShip enemy = Game.AdjacentEnemyStarShip(this, X, Y, false, true);
            if (enemy != null)
            {
                IList<SCGPoint> adj = Game.AdjacentPoints(Location, false);             
                foreach (SCGPoint pt in adj)
                    if (Game.GetObjectAt((int)pt.X, (int)pt.Y) == null)
                        if (Game.AdjacentEnemyStarShip(this, (int)pt.X, (int)pt.Y, false, true) == null)
                        {
                            Game.MoveShipTowardPoint(this, pt);
                            return true;
                        }                
            }
            return false;
        }
    }
}
